﻿using Org.BouncyCastle.Utilities.Encoders;
using smcrypto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Encalgorithm
{
    public class SM3HAMC
    {
        public static string  Signature(string value, string key, bool hexString = true)
        {
            //1.填充0至key,或者hashkey,使其长度为sm3分组长度
            /** BLOCK_LENGTHSM3分组长度 ,64个字节*/
            const int block_length = 64;
            byte[] sm3_key;
            byte[] structured_key = new byte[block_length];
            byte[] IPAD = new byte[block_length];
            byte[] OPAD = new byte[block_length];
            byte[] byteKey;
            if (hexString)
            {
               byteKey = Hex.Decode(key);
            }else
            {
                byteKey=Encoding.UTF8.GetBytes(key);
            }
            
            if (byteKey.Length > block_length)
            {
                sm3_key = SM3Utils.Hash(byteKey);
                //System.arraycopy(sm3_key, 0, structured_key, 0, sm3_key.length);
                Array.Copy(sm3_key, 0, structured_key, 0, sm3_key.Length);
            }
            else
            {
                Array.Copy(byteKey, 0, structured_key, 0, byteKey.Length);
            }
            //2.让处理之后的key 与ipad (分组长度的0x36)做异或运算
            for (int i = 0; i < block_length; i++)
            {
                IPAD[i] = 0x36;
                OPAD[i] = 0x5c;
            }
            byte[] ipadkey = ByteUtils.XOR(structured_key, IPAD);
            //3.将2的结果与text拼接
            byte[] byteText = Encoding.UTF8.GetBytes(value);
            int textLen = byteText.Length;
            byte[] t3 = new byte[block_length + textLen];
            Array.Copy(ipadkey, 0, t3, 0, ipadkey.Length);
            Array.Copy(byteText, 0, t3, ipadkey.Length, byteText.Length);
            //4.将3的结果sm3 哈希
            byte[] t4 = SM3Utils.Hash(t3);
            //5.让处理之后的key 与opad(分组长度的0x5c)做异或运算
            byte[] opadkey = ByteUtils.XOR(structured_key, OPAD);
            //6.4的结果拼接在5之后
            byte[] t6 = new byte[block_length + t4.Length];
            Array.Copy(opadkey, 0, t6, 0, opadkey.Length);
            Array.Copy(t4, 0, t6, opadkey.Length, t4.Length);
            //7.对6做hash
            string res = Encoding.UTF8.GetString(Hex.Encode(SM3Utils.Hash(t6)));
            return res;
        }

       
    }


}
